package sw6.visualschedule.notification;

import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

import sw6.visualschedule.entities.ActivityStatusType;
import sw6.visualschedule.entities.ScheduleActivity;
import sw6.visualschedule.persistence.ScheduleActivityRepo;
import tools.BundleHelper;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;

public class NotificationService extends Service {

    private class BackgroundUpdate extends TimerTask {
        
        @Override
        public void run() {
            // TODO: Lav evt. i servicen et kald direkte til næstkommende aktivitet m. notification time
            final List<ScheduleActivity> activities = mActivityService.getActivities(GregorianCalendar.getInstance().getTime());
            long millisecondsToNotification = 0;
            Boolean taskScheduled = false;
            
            final long currentTime = new Date().getTime();
            
            for (ScheduleActivity activity : activities) {
                if (activity.getInstanceStatus() == ActivityStatusType.FINISHED  || !activity.useNotification()) {
                    continue;
                }

                millisecondsToNotification = currentTime - activity.getInstanceDate().getTime();

               //Log.e("ActivityFound", "Activity: " + activity.getTitle() + " - MS: " + millisecondsToNotification);
                
                // We only want to notify between InstanceDate and 120 seconds in the future
                if (millisecondsToNotification < -1 * 10 * 60 * 1000) {
                    continue;
                } else if (millisecondsToNotification > 0) {
                    continue;
                }

                if (mNotificationTimer != null) {
                    mNotificationTimer.cancel();
                    mNotificationTimer = null;
                }

                //Log.e("ActivityScheduled", "Activity: " + activity.getTitle() + " - MS: " + millisecondsToNotification * -1);
                
                mNotificationTimer = new Timer();
                mNotificationTimer.schedule(new NotificationTask(activity), millisecondsToNotification * -1);
                taskScheduled = true;

                break;
            }

            if (!taskScheduled) {
                setUpdateTimer(1 * 60 * 1000); // 10 minutes * 60 seconds * 1000 milliseconds
            }
        }
    }
    private class NotificationTask extends TimerTask {

        private transient final ScheduleActivity mActivity;

        public NotificationTask(final ScheduleActivity activity) {
            super();
            mActivity = activity;
        }

        @Override
        public void run() {
            final Intent intent = new Intent().setClass(NotificationService.this, NotificationActivity.class);
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            intent.putExtra(BundleHelper.ACTIVITY_ID, mActivity.getId());
            intent.putExtra(BundleHelper.INSTANCE_DATE, mActivity.getInstanceDate().getTime());
            startActivity(intent);
            
            final long updateAgain = new Date().getTime() - mActivity.getInstanceDate().getTime();
            //Log.e("UpdateAgain", "MS: " + updateAgain);
            if (updateAgain >= 0 && updateAgain <= 120 * 1000) {
                setUpdateTimer((int)updateAgain + 1);
            } else {
                setUpdateTimer(0);
            }
        }
        
    }
    private transient ScheduleActivityRepo mActivityService;
    
    private transient Timer mBackgroundUpdateTimer;
    
    private transient Timer mNotificationTimer;
    
    @Override
    public IBinder onBind(final Intent intent) {
        return null;
    }
    
    @Override
    public void onCreate() {
        mActivityService = new ScheduleActivityRepo(this);
    }
    
    @Override
    public void onDestroy() {
        mBackgroundUpdateTimer.cancel();
        mBackgroundUpdateTimer = null;
        
        if (mNotificationTimer != null) {
            mNotificationTimer.cancel();
            mNotificationTimer = null;
        }
    }
    
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        setUpdateTimer(0);
        
        // START_STICKY means we dont want this service to stop until explicitly told so.
        return START_STICKY;
    }
    
    private void setUpdateTimer(final int millisecondsToUpdate) {
        if (mBackgroundUpdateTimer != null) {
            mBackgroundUpdateTimer.cancel();
            mBackgroundUpdateTimer = null;
        }
        
        mBackgroundUpdateTimer = new Timer();
        mBackgroundUpdateTimer.schedule(new BackgroundUpdate(), millisecondsToUpdate);
    }
    
}